home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / cenvid / batch.cmm < prev    next >
Encoding:
Text File  |  1995-10-11  |  20.0 KB  |  796 lines

  1. /*
  2.  * Batch.cmm
  3.  *
  4.  *   Interpret a DOS batch file using CEnvi. This should work on all CEnvi
  5.  *   versions.
  6.  */
  7.  
  8. /* ---------------------------------------------------------------------- */
  9.  
  10. usage()
  11. {
  12.   printf("Use the BATCH command to interpret a DOS batch file under any system\n");
  13.   printf("that CEnvi supports.\n");
  14.   printf("Syntax:\n  BATCH [filename] [args]\nwhere:\n");
  15.   printf("  filename          The .BAT file to be interpreted.\n");
  16.   printf("  args              Any number of arguments for the batch file.\n");
  17.   exit(EXIT_FAILURE);;
  18. }
  19.  
  20. /* ---------------------------------------------------------------------- */
  21.  
  22. /*
  23.  * Setup sets up all system dependent variables. Later, when #ifdef is working
  24.  * this will be replaced using that.
  25.  */
  26.  
  27. search_path = "";       // make it global
  28. errorlevel = 0;
  29. echo = 1;               // echo on
  30.  
  31.  
  32. setup()
  33. {
  34.   if( defined(_NWNLM_) )
  35.     {
  36.       search_path = "SYS:/CENVI/";
  37.     } else {
  38.       if( defined(CMMPATH) ) search_path = CMMPATH;
  39.     }
  40. }
  41.  
  42. /*
  43.  * Change the current directory to the given one. Return 0 if successful.
  44.  */
  45. my_chdir(newdir)
  46. {
  47.   if( defined(_NWNLM_) ) return chdir(newdir);
  48.   if( defined(_DOS_) || defined(_DOS32_) || defined(_WINDOWS_) )
  49.     {
  50.       lReg.ah = 0x3B;
  51.       if !defined(_DOS32_)
  52.          lReg.ds = segment(newdir), lReg.dx = offset(newdir);
  53.       else
  54.          lReg.dx = pointer(newdir);
  55.       interrupt(0x21,lReg,out);
  56.  
  57.       return out.ax;
  58.     }
  59.   if( defined(_NTCON_) || defined(_NTWIN_) )
  60.     {
  61.       return !DynamicLink("KERNEL32","SetCurrentDirectoryA",STDCALL,newdir);
  62.     }
  63.   if( defined(_OS2_) )
  64.     {
  65. #define ORD_DOS32SETCURRENTDIR   255
  66.       return DynamicLink("doscalls",ORD_DOS32SETCURRENTDIR,BIT32,CDECL,newdir);
  67.     }
  68. }
  69.  
  70. special_command = "__@%*&^%";
  71.  
  72. /* ---------------------------------------------------------------------- */
  73.  
  74. /*
  75.  * The count is the number of params, the array is the params. These
  76.  * correspond to %X where X is a digit. We also do %variable% for environment
  77.  * variables, all uppercase.
  78.  *
  79.  * To ease processing, we kill the '\n' too.
  80.  */
  81. substitute_line(line,count,array)
  82. {
  83.   it = ""; i = 0; j = 0;
  84.   while( line[i] )
  85.     {
  86.       if( line[i]!='%' )
  87.         {
  88.           if( line[i]!='\n' )
  89.             {
  90.               it[j++] = line[i];
  91.             }
  92.           i++;
  93.           continue;
  94.         }
  95. // Here we have a substitution...
  96.       if( isdigit(line[i+1]) )
  97.         {
  98.           i += 2;
  99.           num = line[i-1]-'0';
  100.           if( num>=count ) continue;     // no such argument
  101.           for( k=0;array[num][k];k++ ) it[j++] = array[num][k];
  102.         } else {
  103.           if( line[++i]=='%' )
  104.             {
  105.               i++; it[j++] = '%'; continue;
  106.             }
  107.  
  108.           env = ""; offset = 0;
  109.           for( ;line[i] && !isspace(line[i]) && line[i]!='%';i++ )
  110.             env[offset++] = line[i];
  111.  
  112.           if( isspace(line[i]) )
  113.             {
  114.               printf("Variable is not terminated.\n");
  115.               return "";
  116.             }
  117.  
  118.           env[offset] = 0; i++;
  119.           value = "";
  120.           sprintf(to_exec,"if( DataType(%s)==CMM_INT ) sprintf(value,\"%%d\",%s); else if( DataType(%s)==CMM_BYTE ) strcpy(value,%s);\n",env,env,env,env);
  121.           Interpret(to_exec,INTERP_TEXT);
  122.           while( value[0]!='\0' ) { it[j++] = value[0]; value++; }
  123.         }
  124.     }
  125.   it[j] = '\0';
  126.   return it;
  127. }
  128.  
  129. /*
  130.  * Search the appropriate places for the given name. If found, return the
  131.  * full filename else return NULL.
  132.  */
  133. find_cmm(name)
  134. {
  135. // First search the exact filename
  136.   if( fp = fopen(name,"r") )
  137.     {
  138.       fclose(fp);
  139.       return FullPath(name);
  140.     }
  141.  
  142. // Then search the filename converted to '.cmm'
  143.   path = SplitFileName(name);
  144.   sprintf(newname,"%s%s.cmm",path.dir,path.name);
  145.   if( fp = fopen(newname,"r") )
  146.     {
  147.       fclose(fp);
  148.       return FullPath(newname);
  149.     }
  150.  
  151. // Then search the converted filename using the search path.
  152.   strcpy(tmppath,search_path);
  153.   while( tmppath[0]!='\0' )
  154.     {
  155.       while( tmppath[0]==';' ) tmppath++;
  156.       start = tmppath;
  157.       while( tmppath[0]!='\0' && tmppath[0]!=';' ) tmppath++;
  158.       tmppath[0] = '\0'; tmppath++;
  159.       sprintf(newname,"%s%c%s.cmm",start,strchr(start,'/')?'/':'\\',path.name);
  160.       if( fp = fopen(newname,"r") )
  161.         {
  162.           fclose(fp);
  163.           return FullPath(newname);
  164.         }
  165.     }
  166.  
  167. // Else not found
  168.   return NULL;
  169. }
  170.  
  171. /* ---------------------------------------------------------------------- */
  172.  
  173. next_token(line,index)
  174. {
  175.   command = ""; j = 0;
  176.   while( isspace(line[index]) ) index++;
  177.   while( line[index] && !isspace(line[index]) )
  178.     command[j++] = line[index++];
  179.   while( isspace(line[index]) ) index++;
  180.   command[j] = '\0';
  181.   return command;
  182. }
  183.  
  184. /* ---------------------------------------------------------------------- */
  185.  
  186. // All these functions return the name of the label we have to GOTO, or ""
  187. // if none.
  188.  
  189.  
  190. /*
  191.  * We just ignore the line.
  192.  */
  193. REM_handler(the_line,ptr,line_num)
  194. {
  195.   return "";
  196. }
  197.  
  198.  
  199.  
  200. /*
  201.  * We dump the text to the terminal. The exceptions are if we have 'echo on'
  202.  * or 'echo off'.
  203.  */
  204. ECHO_handler(the_line,ptr,line_num)
  205. {
  206.   if( !stricmp(the_line+ptr,"ON") )
  207.     {
  208.       echo = 1;
  209.       return "";
  210.     }
  211.   if( !stricmp(the_line+ptr,"OFF") )
  212.     {
  213.       echo = 0;
  214.       return "";
  215.     }
  216.  
  217.   printf("%s\n",the_line+ptr);
  218.   return "";
  219. }
  220.  
  221.  
  222.  
  223. /*
  224.  * If no parameter, print the current directory. Otherwise, set the current
  225.  * directory to what is given.
  226.  */
  227. CD_handler(the_line,ptr,line_num)
  228. {
  229.   if( the_line[ptr]=='\0' )
  230.     {
  231.       printf("%s\n",getcwd(buffer));
  232.       return "";
  233.     }
  234.   if( my_chdir(the_line+ptr) )
  235.     printf("The system cannot find the path specified at line %d.\n",line_num);
  236.   return "";
  237. }
  238.  
  239.  
  240. /*
  241.  * Simply clear the screen.
  242.  */
  243. CLS_handler(the_line,ptr,line_num)
  244. {
  245.   ScreenClear();
  246.   return "";
  247. }
  248.  
  249.  
  250. /*
  251.  * TYPE a file to the terminal. This is an incredibly simple routine. Use
  252.  * MORE for some options.
  253.  */
  254. TYPE_handler(the_line,ptr,line_num)
  255. {
  256.   if( fp = fopen(the_line+ptr,"r") )
  257.     {
  258.       while( 1 )
  259.         {
  260.           if( (newline = fgets(fp))==NULL ) break;
  261.           printf("%s",newline);
  262.         }
  263.       fclose(fp);
  264.     } else {
  265.       printf("Unable to open file \"%s\" at line %d.\n",the_line+ptr,line_num);
  266.     }
  267.   return "";
  268. }
  269.  
  270.  
  271.  
  272. /*
  273.  * Since the variable we need to change is a local to one of our callers,
  274.  * we pass back a command to it to tell it to do what we want.
  275.  */
  276. SHIFT_handler(the_line,ptr,line_num)
  277. {
  278.   return special_command;
  279. }
  280.  
  281.  
  282.  
  283. /*
  284.  * Just waits for the user to press any key.
  285.  */
  286. PAUSE_handler(the_line,ptr,line_num)
  287. {
  288.   printf("Press any key when ready . . . "); fflush(stdout);
  289.   getch();
  290.   printf("\n");
  291.   return "";
  292. }
  293.  
  294.  
  295.  
  296. /*
  297.  * Invoke a new batch file and return to this one when it finishes
  298.  */
  299. CALL_handler(the_line,ptr,line_num)
  300. {
  301. // Set up a new argc/argv array and call main again.
  302.   strcpy(newargv[0],"CEnvi");
  303.   newargc = 1;
  304.   while( the_line[ptr]!='\0' )
  305.     {
  306.       command = next_token(the_line,ptr);
  307.       strcpy(newargv[newargc++],command);
  308.       while( isspace(the_line[ptr]) ) ptr++;
  309.     }
  310.   main(newargc,newargv);
  311.   return "";
  312. }
  313.  
  314.  
  315.  
  316. /*
  317.  * The _EVIL_ goto command...
  318.  */
  319. GOTO_handler(the_line,ptr,line_num)
  320. {
  321.   return the_line+ptr;
  322. }
  323.  
  324.  
  325.  
  326. /*
  327.  * No, this does not simulate a person skilled in dealing with evil
  328.  * Egyptian gods...
  329.  */
  330. SET_handler(the_line,ptr,line_num)
  331. {
  332.   if( defined(_NWNLM_) )
  333.     {
  334.       printf("Netware has no environment variables at line %d.\n",line_num);
  335.       return "";
  336.     }
  337.  
  338.   if( the_line[ptr]=='\0' )
  339.     {
  340.       array = getenv();
  341.       for( ii=0;ii<GetArraySpan(array);ii++ )
  342.         {
  343.           printf("%s=%s\n",array[ii],getenv(array[ii]));
  344.         }
  345.       return "";
  346.     }
  347.  
  348. // Else we extract the name and see if we have a '=' or not.
  349.   command = next_token(the_line,ptr);
  350.  
  351.   if( (where = strchr(command,'='))!=NULL )
  352.     {
  353.       where[0] = '\0';
  354.       strcpy(env_var,command);
  355.       strcpy(new_val,where+1);
  356.     } else {
  357.       strcpy(env_var,command);
  358.       new_val = NULL;
  359.       if( the_line[ptr]=='=' )
  360.         {
  361.           while( isspace(the_line[++ptr]) );
  362.           strcpy(new_val,the_line+ptr);
  363.         }
  364.     }
  365.  
  366.   if( new_val==NULL )
  367.     {
  368.       printval = getenv(env_var);
  369.       printf("%s=%s\n",env_var,(printval!=NULL)?printval:"");
  370.     } else {
  371.       putenv(env_var,new_val);
  372.     }
  373.   return "";
  374. }
  375.  
  376.  
  377.  
  378. /*
  379.  * A simple looping construct.
  380.  */
  381. FOR_handler(the_line,ptr,line_num)
  382. {
  383.   command = next_token(the_line,ptr);
  384.   if( command[0]!='%' )
  385.     {
  386.       printf("Illegal loop variable in FOR statement at line %d.\n",line_num);
  387.       return "";
  388.     }
  389.   strcpy(loop_variable,command);
  390.   command = next_token(the_line,ptr);
  391.  
  392.   if( stricmp(command,"IN") )
  393.     {
  394.       printf("Malformed FOR statement, missing IN clause at line %d.\n",line_num);
  395.       return "";
  396.     }
  397.   if( the_line[ptr++]!='(' )
  398.     {
  399.       printf("Malformed FOR statement, missing open parenthesis at line %d.\n",line_num);
  400.     }
  401.  
  402. // Next we need to collect all the things we index over...
  403.  
  404.   undefine(list); list_index = 0;
  405.   done = 0;
  406.   while( !done )
  407.     {
  408.       command = next_token(the_line,ptr);
  409.       if( command[strlen(command)-1]==')' )
  410.         {
  411.           command[strlen(command)-1] = '\0'; done = 1;
  412.         }
  413.       if( command[0]!='\0' )
  414.         {
  415.           if( strcspn(command,"*?")==strlen(command) )
  416.             {
  417.               strcpy(list[list_index++],command);
  418.             } else {
  419.               files = Directory(command);
  420.               for( i=0;files && i<=GetArraySpan(files);i++ )
  421.                 strcpy(list[list_index++],files[i].name);
  422.             }
  423.         }
  424.     }
  425.  
  426.   command = next_token(the_line,ptr);
  427.   if( stricmp(command,"DO") )
  428.     {
  429.       printf("Malformed FOR statement after arg list at line %d.\n",line_num);
  430.       return "";
  431.     }
  432.   for( i=0;i<list_index;i++ )
  433.     {
  434.       strcpy(to_do,the_line+ptr);
  435.       while( (indx = strstr(to_do,loop_variable))!=NULL )
  436.         {
  437.           index = indx-to_do;
  438.           strcpy(new_do,to_do);
  439.           strcpy(new_do+index,list[i]);
  440.           strcat(new_do,to_do+index+strlen(loop_variable));
  441.           strcpy(to_do,new_do);
  442.         }
  443.       process_command(to_do,line_num);
  444.     }
  445.   return "";
  446. }
  447.  
  448.  
  449.  
  450. /*
  451.  * And the testing construct.
  452.  */
  453. IF_handler(the_line,ptr,line_num)
  454. {
  455.   command = next_token(the_line,ptr);
  456.  
  457.   notted = 0;
  458.  
  459.   if( !stricmp(command,"NOT") )
  460.     {
  461.       notted = 1;
  462.       command = next_token(the_line,ptr);
  463.     }
  464.  
  465. // Here we decide which of the three considitions we have.
  466.   if( !stricmp(command,"EXIST") )
  467.     {
  468.       command = next_token(the_line,ptr);
  469.       
  470.       exist = (fp = fopen(command,"r"))!=NULL;
  471.       if( fp ) fclose(fp);
  472.       if( notted^exist )
  473.         {
  474.           return process_command(=the_line+ptr,line_num);
  475.         }
  476.       return "";
  477.     }
  478.   
  479.   if( !stricmp(command,"ERRORLEVEL") )
  480.     {
  481.       command = next_token(the_line,ptr,line_num);
  482.       
  483.       testlevel = atoi(command);
  484.       
  485.       command = next_token(the_line,ptr);
  486.       
  487.       if( notted^(errorlevel>=testlevel) )
  488.         {
  489.           return process_command(=the_line+ptr,line_num);
  490.         }
  491.       return "";
  492.     }
  493.  
  494.   if( where = strstr(command,"==") )
  495.     {
  496.       where[0] = 0; where += 2;
  497.       if( notted^!stricmp(command,where) )
  498.         {
  499.           return process_command(=the_line+ptr,line_num);
  500.         }
  501.       return "";
  502.     }
  503.  
  504.  
  505.   printf("Unrecognized IF syntax beginning with %s at line %d.\n",command,line_num);
  506.   return "";
  507. }
  508.  
  509.  
  510. command_names = {
  511.   "REM", "ECHO", "CD", "CLS", "TYPE", "SHIFT", "CAUSE", "CALL", "SET",
  512.   "GOTO", "FOR", "IF", "PAUSE"
  513. };
  514.  
  515. /* ---------------------------------------------------------------------- */
  516.  
  517. process_command(the_line,line_num)
  518. {
  519.   ptr = 0; while( isspace(the_line[ptr]) ) ptr++;
  520.  
  521. // If the line is blank, we skip it
  522.  
  523.   if( the_line[ptr]=='\n' || the_line[ptr]=='\0' ) return "";
  524.  
  525. // If it is a ':LABEL' line, we skip it.
  526.  
  527.   if( the_line[ptr]==':' ) return "";
  528.  
  529.  
  530. // Else it is either an internal command, a .CMM script, or we dump it
  531. // to the system processor.
  532.  
  533.   mark = ptr;
  534.   command = next_token(the_line,ptr);
  535.  
  536. // ----------------------------------------------------------------------
  537. // Here we process all internal commands
  538. // ----------------------------------------------------------------------
  539.  
  540.   for( i=0;i<=GetArraySpan(command_names);i++ )
  541.     {
  542.       if( !stricmp(command_names[i],command) )
  543.         {
  544.           sprintf(func_name,"%s_handler",command_names[i]);
  545.           return function(func_name,the_line,ptr,line_num);
  546.         }
  547.     }
  548.  
  549. // ----------------------------------------------------------------------
  550. // We check to see if it is a drive designation
  551. // ----------------------------------------------------------------------
  552.  
  553.   if( command[1]==':' && strlen(command)==2 )
  554.     {
  555. #define ORD_DOS32SETDEFAULTDISK  220
  556.       if( defined(_OS2_) )
  557.         {
  558.           DynamicLink("doscalls",ORD_DOS32SETDEFAULTDISK,BIT32,CDECL,
  559.                       toupper(command[0])-'A'+1);
  560.         }
  561.       if( defined(_NTWIN_) || defined(_NTCON_) )
  562.         {
  563.           CD_handler(command,0,line_num);
  564.         }
  565.       if( defined(_WINDOWS_) || defined(_DOS_) || defined(_DOS32_) )
  566.         {
  567.           lReg.ah = 0x0E;
  568.           lReg.dl = toupper(command[0]) - 'A';
  569.           interrupt(0x21,lReg);
  570.         }
  571.       return "";
  572.     }
  573.  
  574. // -----------------------------------------------------------------------
  575. // Otherwise, it is either a CMM script or we dump it to the command shell
  576. // Here we check to see if we can find a .CMM file to run.
  577. // -----------------------------------------------------------------------
  578.  
  579.   if( (filename = find_cmm(command)) )
  580.     {
  581.       strcat(filename," ");
  582.       strcat(filename,the_line+ptr);
  583.       errorlevel = Interpret(filename,
  584.                              INTERP_FILE | 
  585.                              INTERP_NOINHERIT_LOCAL |
  586.                              INTERP_NOINHERIT_GLOBAL );
  587.       return "";
  588.     }
  589.  
  590.   errorlevel = system(the_line+mark);
  591.  
  592.   return "";
  593. }
  594.  
  595. /* ---------------------------------------------------------------------- */
  596.  
  597. /*
  598.  * Ok, we have a list of internal commands. All other commands are
  599.  * either CMM scripts which we interpret, else they are system commands
  600.  * which we execute as appropriate for each system.
  601.  *
  602.  * Lines beginning with a ':' are ignored except when searching for
  603.  * GOTO targets.
  604.  */
  605.  
  606. main(argc,argv)
  607. {
  608.   setup();
  609.   plus = 1;             // the offset into the parameter array for substitution
  610.  
  611.  
  612.   if( argc<2 || !strcmp(argv[1],"/?") )
  613.     {
  614.       usage();
  615.     }
  616.  
  617.   if( (fp = fopen(argv[1],"r"))==NULL )
  618.     {
  619.       path = SplitFileName(argv[1]);
  620.       sprintf(newname,"%s%s.bat",path.dir,path.name);
  621.       fp = fopen(newname,"r");
  622.     }
  623.   if( fp==NULL )
  624.     {
  625.       printf("Could not open source file \"%s\" for reading.\n",argv[1]);
  626.       return 1;
  627.     }
  628.  
  629.   line_count = 0;
  630.   while( 1 )
  631.     {
  632.       if( (newline = fgets(fp))==NULL ) break;
  633.       strcpy( lines[line_count++],newline);
  634.     }
  635.   fclose(fp);
  636.  
  637. // All right. We have the file in memory as a sequence of lines. Start doing them.
  638.  
  639.   for( i = 0;i<line_count;i++ )
  640.     {
  641.       strcpy(the_line,lines[i]);
  642.  
  643. // First we do any parameter substitution in the line
  644.       the_line = substitute_line(the_line,argc-plus,argv+plus);
  645.  
  646.       while( isspace(the_line[0]) ) the_line++;
  647.       if( the_line[0]=='@' )
  648.         {
  649.           echo_it = 0; the_line++;
  650.         } else {
  651.           echo_it = echo;
  652.         }
  653.  
  654.       if( echo_it ) printf("\n%s>%s\n",FullPath("."),the_line);
  655.  
  656.       redir_stdout = NULL;
  657.       redir_stdin = NULL;
  658.       redir_new = NULL;
  659.       to_delete = NULL;
  660.       mode = "";
  661.       in_quotes = 0;
  662.       start_from = 0;
  663.  
  664.       while( the_line[0] )
  665.         {
  666.           next_line = "";
  667.  
  668.           while( (loc = strcspn(the_line+start_from,"\"|<>"))
  669.                 !=strlen(the_line+start_from) )
  670.             {
  671.               loc += start_from;
  672.               if( the_line[loc]=='\"' )
  673.                 {
  674.                   in_quotes = 1 - in_quotes;
  675.                   start_from = loc+1;
  676.                   continue;
  677.                 }
  678.  
  679.               if( in_quotes )
  680.                 {
  681.                   start_from = loc+1;
  682.                   continue;
  683.                 }
  684.  
  685.               if( the_line[loc]=='<' )
  686.                 {
  687.                   if( redir_stdin )
  688.                     {
  689.                       fprintf(stderr,"Input already redirected.\n");
  690.                       exit(EXIT_FAILURE);
  691.                     }
  692.  
  693.                   newloc = loc+1;
  694.                   while( isspace(the_line[newloc]) ) newloc++;
  695.                   locstart = newloc;
  696.                   while( the_line[newloc] && !isspace(the_line[newloc]) )
  697.                     newloc++;
  698.                   tmp = the_line[newloc]; the_line[newloc] = 0;
  699.                   strcpy(redir_stdin,the_line+locstart);
  700.                   the_line[newloc] = tmp;
  701.                   strcpy(the_line+loc,the_line+newloc);
  702.                   continue;
  703.                 }
  704.               if( the_line[loc]=='>' )
  705.                 {
  706.                   if( redir_stdout )
  707.                     {
  708.                       fprintf(stderr,"Output already redirected.\n");
  709.                       exit(EXIT_FAILURE);
  710.                     }
  711.  
  712.                   mode = "wt";
  713.                   newloc = loc+1;
  714.                   if( the_line[newloc]=='>' )
  715.                     {
  716.                       mode = "at";
  717.                       newloc++;
  718.                     }
  719.  
  720.                   while( isspace(the_line[newloc]) ) newloc++;
  721.                   locstart = newloc;
  722.                   while( the_line[newloc] && !isspace(the_line[newloc]) )
  723.                     newloc++;
  724.                   tmp = the_line[newloc]; the_line[newloc] = 0;
  725.                   strcpy(redir_stdout,the_line+locstart);
  726.                   the_line[newloc] = tmp;
  727.                   strcpy(the_line+loc,the_line+newloc);
  728.                   continue;
  729.                 }
  730.  
  731.               if( the_line[loc]=='|' )
  732.                 {
  733.                   if( redir_stdout )
  734.                     {
  735.                       fprintf(stderr,"Output is already redirected to a file.\n");
  736.                       exit(EXIT_FAILURE);
  737.                     }
  738.                   mode = "wt";
  739.                   strcpy(next_line,the_line+loc+1);
  740.                   the_line[loc] = 0;
  741.                   strcpy(redir_new,tmpnam());
  742.                   strcpy(redir_stdout,redir_new);
  743.                   break;
  744.                 }
  745.             }
  746.  
  747.           if( redir_stdout && !freopen(redir_stdout,mode,stdout) )
  748.             {
  749.               fprintf(stderr,"Unable to open output redirection file \"%s\".\n",
  750.                       redir_stdout);
  751.               exit(EXIT_FAILURE);
  752.             }
  753.  
  754.           if( redir_stdin && !freopen(redir_stdin,"r",stdin) )
  755.             {
  756.               fprintf(stderr,"Unable to open input redirection file \"%s\".\n",
  757.                       redir_stdin);
  758.               exit(EXIT_FAILURE);
  759.             }
  760.  
  761.           label = process_command(the_line,i+1);
  762.           if( to_delete ) remove(to_delete);
  763.           to_delete = NULL;
  764.           if( redir_stdout ) { fclose(stdout); redir_stdout = NULL; }
  765.           if( redir_stdin ) { fclose(stdin); }
  766.           redir_stdin = redir_new; to_delete = redir_new; redir_new = NULL;
  767.  
  768.           strcpy(the_line,next_line);
  769.         }
  770.  
  771.       if( !stricmp(label,special_command) )
  772.         {
  773.           plus++; continue;
  774.         }
  775.  
  776.       if( label[0]!='\0' )
  777.         {
  778.           yep = 0;
  779.           length = strlen(label);
  780.           for( j=0;!yep && j<line_count;j++ )
  781.             {
  782.               if( lines[j][0]==':' && !strncmp(lines[j]+1,label,length) )
  783.                 {
  784.                   yep = 1;
  785.                   i = j - 1;
  786.                 }
  787.             }
  788.           if( !yep )
  789.             {
  790.               printf("Label \"%s\" not found.\n",label);
  791.               return 1;
  792.             }
  793.         }
  794.     }
  795. }
  796.